<script setup lang="ts">
import { ref, onMounted, onBeforeUnmount, watch, computed } from 'vue'
import { showToast, Icon } from 'vant'
import { useChatStore } from '@/store/chat'
import MessageList from './components/MessageList.vue'
import ChatInput from './components/ChatInput.vue'
import WelcomeMessage from './components/WelcomeMessage.vue'

type MessageType = {
  type: 'user' | 'ai';
  content: string;
} & (
  | { 
      hasThinking: true;
      thinking: {
        content: string;
        done: boolean;
        time: number;
        startTime?: number;
      };
    }
  | {
      hasThinking?: false;
      thinking?: undefined;
    }
);

const chatStore = useChatStore()

const historyMessages = ref<MessageType[]>([])

const sessionId = ref('')
const message = computed(() => chatStore.connectionState.assistantMessage)
const loading = computed(() => chatStore.connectionState.assistantLoading)
const error = computed(() => chatStore.connectionState.error)

const DB_ASSISTANT_PROMPT = `system：我希望你作为智数数据库在线编程平台的一个专业的数据库助教，
帮助用户解答关于数据库的各种问题。你精通SQL、数据库设计、性能优化、事务处理等领域的知识。
请用专业、准确但通俗易懂的方式回答问题，需要时可以提供代码示例。风格要求：条理清晰，易于理解。
提供具体示例，帮助用户更好地理解抽象概念。对复杂问题进行分解，并逐步引导用户掌握解决方法。
如果用户的问题不清晰，可以请求澄清。如果问题超出数据库领域，礼貌地将话题引导回数据库相关内容。
现在，请根据用户的问题，以专业数据库助教的身份提供帮助。`

const isFirstMessage = ref(true)

const initSession = () => {
  if (chatStore.currentAssistantSessionId) {
    sessionId.value = chatStore.currentAssistantSessionId
    const savedMessages = chatStore.getCurrentAssistantMessages()
    if (savedMessages && savedMessages.length > 0) {
      historyMessages.value = savedMessages
      isFirstMessage.value = false
    } else {
      isFirstMessage.value = true
    }
  } else {
    sessionId.value = chatStore.generateSessionId()
    chatStore.currentAssistantSessionId = sessionId.value
    isFirstMessage.value = true
  }
}

initSession()

const handleSendMessage = (text: string) => {
  if (!text.trim()) return
  
  if (isFirstMessage.value) {
    const promptedMessage = `${DB_ASSISTANT_PROMPT}\n\nuser：${text}`
    
    historyMessages.value.push({
      type: 'user',
      content: text
    })
    
    historyMessages.value.push({
      type: 'ai',
      content: '',
      hasThinking: false
    })
    
    chatStore.sendAssistantMessage(sessionId.value, promptedMessage)
    // chatStore.sendDifyMessage(sessionId.value, promptedMessage)
    isFirstMessage.value = false
  } else {
    historyMessages.value.push({
      type: 'user',
      content: text
    })
    
    historyMessages.value.push({
      type: 'ai',
      content: '',
      hasThinking: false
    })
    
    chatStore.sendAssistantMessage(sessionId.value, text)
    // chatStore.sendDifyMessage(sessionId.value, text)
  }
  
  scrollToBottom()
  shouldAutoScroll.value = true
  
  chatStore.saveAssistantMessages(sessionId.value, historyMessages.value)
}

const handleStopStream = () => {
  chatStore.stopStream('assistant')
  
  const lastIndex = historyMessages.value.length - 1
  if (lastIndex >= 0 && historyMessages.value[lastIndex].type === 'ai') {
    const lastAIMessage = historyMessages.value[lastIndex]
    
    if (lastAIMessage.hasThinking && lastAIMessage.thinking) {
      const thinkingMessage = lastAIMessage as Extract<MessageType, { hasThinking: true }>;
      thinkingMessage.thinking.done = true;
      if (!thinkingMessage.thinking.time || thinkingMessage.thinking.time <= 0) {
        if (thinkingMessage.thinking.startTime) {
          const elapsedTime = Date.now() - thinkingMessage.thinking.startTime;
          thinkingMessage.thinking.time = Math.max(1, Math.round(elapsedTime / 1000));
        } else {
          thinkingMessage.thinking.time = 1;
        }
      }
    }
    if (!lastAIMessage.content && (!lastAIMessage.hasThinking || 
        (lastAIMessage.hasThinking && !lastAIMessage.thinking?.content))) {
      lastAIMessage.content = '回答已中断'
    }
  }
}

const clearHistory = () => {
  if (loading.value) {
    handleStopStream()
  }
  
  historyMessages.value = []
  chatStore.clearAssistantMessage()
  
  chatStore.clearAssistantMessages(sessionId.value)
  
  sessionId.value = chatStore.generateSessionId()
  chatStore.currentAssistantSessionId = sessionId.value
  
  // 重置为新会话
  isFirstMessage.value = true
}

const shouldAutoScroll = ref(true)
const isUserScrolling = ref(false)
const scrollTimer = ref<ReturnType<typeof setTimeout> | null>(null)
const chatContent = ref<HTMLDivElement>()

const scrollToBottom = () => {
  requestAnimationFrame(() => {
    if (chatContent.value) {
      chatContent.value.scrollTo({
        top: chatContent.value.scrollHeight,
        behavior: 'auto'
      })
    }
  })
}

const isScrolledToBottom = (): boolean => {
  if (!chatContent.value) return true
  
  const { scrollTop, scrollHeight, clientHeight } = chatContent.value
  return scrollHeight - scrollTop - clientHeight < 20
}

const handleScroll = () => {
  if (scrollTimer.value) {
    clearTimeout(scrollTimer.value)
  }
  isUserScrolling.value = true
  shouldAutoScroll.value = isScrolledToBottom()
  scrollTimer.value = setTimeout(() => {
    isUserScrolling.value = false
  }, 150)
}

const parseAIMessage = (msg: string) => {
  const result = {
    content: '',
    thinking: '',
    thinkingDone: false
  }
  
  try {
    let originalMsg = msg;
    const thinkOpenTag = originalMsg.indexOf('<think>');
    const thinkCloseTag = originalMsg.indexOf('</think>');
    
    if (thinkOpenTag !== -1) {
      if (thinkCloseTag !== -1) {
        result.thinking = originalMsg.substring(thinkOpenTag + 7, thinkCloseTag).trim();
        result.thinkingDone = true;
        originalMsg = originalMsg.replace(/<think>.*?<\/think>/s, '');
      } else {
        result.thinking = originalMsg.substring(thinkOpenTag + 7).trim();
        result.thinkingDone = false;
        originalMsg = '';
      }
    }
    
    result.content = originalMsg.trim();
    
  } catch (e) {
    console.error('解析AI消息失败:', e);
  }
  
  return result;
}

const watchMessage = () => {
  if (!message.value) return
  
  const lastIndex = historyMessages.value.length - 1
  if (lastIndex >= 0 && historyMessages.value[lastIndex].type === 'ai') {
    const lastAIMessage = historyMessages.value[lastIndex];
    const parsedMessage = parseAIMessage(message.value);
    const hasThinkStartTag = message.value.includes('<think>');
    const hasThinkEndTag = message.value.includes('</think>');
    
    if (hasThinkStartTag && parsedMessage.thinking.trim() !== '') {
      if (!lastAIMessage.hasThinking) {
        const thinkingMessage: Extract<MessageType, { hasThinking: true }> = {
          ...lastAIMessage,
          hasThinking: true,
          thinking: {
            content: parsedMessage.thinking,
            done: hasThinkEndTag,
            time: 0,
            startTime: Date.now()
          }
        };
        historyMessages.value[lastIndex] = thinkingMessage;
      } else {
        const thinkingMessage = lastAIMessage as Extract<MessageType, { hasThinking: true }>;
        thinkingMessage.thinking.content = parsedMessage.thinking;
        if (hasThinkEndTag && !thinkingMessage.thinking.done) {
          thinkingMessage.thinking.done = true;
          if (thinkingMessage.thinking.startTime) {
            const elapsedTime = Date.now() - thinkingMessage.thinking.startTime;
            thinkingMessage.thinking.time = Math.max(1, Math.round(elapsedTime / 1000));
          } else {
            thinkingMessage.thinking.time = 3; 
          }
        }
      }
    } else if (!hasThinkStartTag && lastAIMessage.hasThinking) {
      const nonThinkingMessage: Extract<MessageType, { hasThinking?: false }> = {
        ...lastAIMessage,
        hasThinking: false,
        thinking: undefined
      };
      
      historyMessages.value[lastIndex] = nonThinkingMessage;
    }
    
    if (!hasThinkStartTag || hasThinkEndTag) {
      historyMessages.value[lastIndex].content = parsedMessage.content;
    }
    
    chatStore.saveAssistantMessages(sessionId.value, historyMessages.value)
    
    if (shouldAutoScroll.value && !isUserScrolling.value) {
      scrollToBottom()
    }
  }
}

const watchError = (): void => {
  if (error.value) {
    showToast(error.value)
    setTimeout(() => {
      chatStore.connectionState.error = ''
    }, 100)
  }
}

onMounted(() => {
  if (chatContent.value) {
    chatContent.value.addEventListener('scroll', handleScroll)
  }
})

onBeforeUnmount(() => {
  if (chatContent.value) {
    chatContent.value.removeEventListener('scroll', handleScroll)
  }
  if (scrollTimer.value) {
    clearTimeout(scrollTimer.value)
  }
})

watch(message, () => {
  watchMessage()
})

watch(error, (newVal) => {
  if (newVal) {
    watchError()
  }
})

watch(loading, (newVal: boolean, oldVal: boolean) => {
  if (newVal === false && oldVal === true) {
    shouldAutoScroll.value = true
  }
})
</script>

<template>
  <div class="assistant-container">
    <div class="header">
      <div class="placeholder" style="width: 64px;"></div>
      <div class="title">智能助教</div>
      <div class="right-button" @click="clearHistory">
        <div class="clear-button">
          <Icon name="delete-o" size="16" />
          <span>清空</span>
        </div>
      </div>
    </div>
    
    <div class="chat-content" ref="chatContent">
      <WelcomeMessage v-if="historyMessages.length === 0" />
      
      <MessageList
        v-else
        :messages="historyMessages"
        :loading="loading"
      />
    </div>

    <ChatInput 
      :loading="loading"
      @send="handleSendMessage"
      @stop="handleStopStream"
    />
  </div>
</template>

<style lang="scss" scoped>
.assistant-container {
  display: flex;
  flex-direction: column;
  height: 100vh;
  background-color: #f7f8fa;
  position: relative;
  
  .header {
    display: flex;
    align-items: center;
    padding: 12px 16px;
    background-color: #ffffff;
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.1);
    position: sticky;
    top: 0;
    left: 0;
    right: 0;
    z-index: 10;
    
    .placeholder {
      flex-shrink: 0;
    }
    
    .title {
      flex: 1;
      text-align: center;
      font-size: 18px;
      font-weight: 500;
      color: #333;
    }
    
    .right-button {
      flex-shrink: 0;
      .clear-button {
        display: flex;
        align-items: center;
        gap: 4px;
        padding: 6px 12px;
        background-color: #f5f5f5;
        border-radius: 16px;
        color: #666;
        font-size: 14px;
        
        &:active {
          background-color: #e8e8e8;
        }
      }
    }
  }
  
  .chat-content {
    flex: 1;
    overflow-y: auto;
    padding: 16px;
    padding-bottom: 150px;
  }
}
</style>